package com.joysuch.wwyt.config.mybatis;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.TableInfoHelper;
import com.joysuch.wwyt.core.security.ShiroUser;
import com.joysuch.wwyt.core.support.Context;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Objects;
import java.util.Optional;

import static com.joysuch.wwyt.common.constant.MybatisFillConstant.*;

/**
 * MyBatis 字段填充处理
 * Created by jingwk on 2021/03/25.
 */
@Component
public class MybatisFillHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        ShiroUser user = Context.getCurrentUser();
        if(Objects.nonNull(user)){
            this.setInsertFieldValByName(TENENT_ID, user.getTenentId(), metaObject);
            this.setInsertFieldValByName(ORG_CODE, user.getCompanyCode(), metaObject);
            this.setInsertFieldValByName(CREATE_BY, user.getRealUserId(), metaObject);
            this.setInsertFieldValByName(UPDATE_BY, user.getRealUserId(), metaObject);
        }
        this.setInsertFieldValByName(CREATE_TIME, new Date(), metaObject);
        this.setInsertFieldValByName(UPDATE_TIME, new Date(), metaObject);
        this.setInsertFieldValByName(DELETE_FLAG, "0", metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        ShiroUser user = Context.getCurrentUser();
        if(Objects.nonNull(user)){
            this.setUpdateFieldValByName(UPDATE_BY, user.getRealUserId(), metaObject);
            this.setUpdateFieldValByName(TENENT_ID, user.getTenentId(), metaObject);
            this.setUpdateFieldValByName(ORG_CODE, user.getCompanyCode(), metaObject);
        }
        this.setUpdateFieldValByName(UPDATE_TIME, DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN), metaObject);
    }

    /**
     * 填充判断逻辑
     *
     * @param fieldName  填充字段名
     * @param fieldVal   填充字段值
     * @param metaObject 元数据类
     * @param fieldFill  填充策略
     * @return
     */
    @Override
    public boolean isFill(String fieldName, Object fieldVal, MetaObject metaObject, FieldFill fieldFill) {
        TableInfo tableInfo = metaObject.hasGetter(MP_OPTLOCK_ET_ORIGINAL) ? TableInfoHelper.getTableInfo(metaObject.getValue(MP_OPTLOCK_ET_ORIGINAL).getClass()) : TableInfoHelper.getTableInfo(metaObject.getOriginalObject().getClass());
        if (Objects.nonNull(tableInfo)) {
            Optional<TableFieldInfo> first = tableInfo.getFieldList().stream().filter((e) -> {
                //匹配规则：字段名称和字段类型一致
                return e.getProperty().equals(fieldName) && e.getPropertyType().equals(fieldVal.getClass());
            }).findFirst();
            if (first.isPresent()) {
                FieldFill fill = first.get().getFieldFill();
                return fill.equals(fieldFill) || FieldFill.INSERT_UPDATE.equals(fill);
            }
        }
        return false;
    }
}
